home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-07-14 | 2.7 KB | 144 lines | [TEXT/MPCC] |
- /*********************************************************************
- Project : GUSI - Grand Unified Socket Interface
- File : HandleSocket.cp- Handle sockets
- Author : Matthias Neeracher <neeri@iis.ee.ethz.ch>
- Language : MPW C++
-
- $Log: GUSIFile.cp,v $
- *********************************************************************/
-
- #include "GUSI_P.h"
-
- #include <IOCtl.h>
-
- extern "C" int OpenHandle(Handle h, int oflag);
-
- class HandleSocket : public Socket {
- friend int OpenHandle(Handle h, int oflag);
- protected:
- HandleSocket(Handle h, int oflag);
- public:
- virtual int read(void * buffer, int buflen);
- virtual int write(void * buffer, int buflen);
- virtual int ioctl(unsigned int request, void *argp);
- virtual long lseek(long offset, int whence);
- virtual int ftruncate(long offset);
- private:
- Handle data;
- long pos;
- Boolean append;
- };
-
- /************************ HandleSocket members ************************/
-
- HandleSocket::HandleSocket(Handle h, int oflag)
- : Socket(), data(h), pos(0)
- {
- if (oflag & O_TRUNC)
- SetHandleSize(data, 0);
- append = (oflag & O_APPEND) != 0;
- }
-
- int HandleSocket::read(void * buffer, int buflen)
- {
- long length = buflen;
- long left = GetHandleSize(data)-pos;
-
- if (length > left)
- length = left;
-
- if (length) {
- HLock(data);
- memcpy(buffer, *data+pos, length);
- pos += length;
- HUnlock(data);
- }
-
- return int(length);
- }
-
- int HandleSocket::write(void * buffer, int buflen)
- {
- if (append)
- pos = GetHandleSize(data);
-
- long size = GetHandleSize(data);
- if (pos+buflen > size) {
- SetHandleSize(data, pos+buflen);
- while (size < pos)
- (*data)[size++] = 0;
- }
- if (buflen) {
- HLock(data);
- memcpy(*data+pos, buffer, buflen);
- pos += buflen;
- HUnlock(data);
- }
-
- return buflen;
- }
-
- int HandleSocket::ioctl(unsigned int request, void *argp)
- {
- switch (request) {
- case FIONREAD:
- *(long *) argp = GetHandleSize(data) - pos;
-
- return 0;
- default :
- return Socket::ioctl(request, argp);
- }
- }
-
- long HandleSocket::lseek(long offset, int whence)
- {
- long newPos;
-
- switch (whence) {
- case SEEK_CUR:
- newPos = pos+offset;
- break;
- case SEEK_END:
- newPos = GetHandleSize(data)+offset;
- break;
- case SEEK_SET:
- newPos = offset;
- break;
- default:
- return GUSI_error(EINVAL);
- }
- if (newPos < 0)
- return GUSI_error(EINVAL);
- else
- return pos = newPos;
- }
-
- int HandleSocket::ftruncate(long offset)
- {
- if (offset > GetHandleSize(data)) {
- lseek(offset, SEEK_SET);
- write(nil, 0);
- } else
- SetHandleSize(data, offset);
-
- return 0;
- }
-
- int OpenHandle(Handle h, int oflag)
- {
- int fd;
- Socket * sock = new HandleSocket(h, oflag);
-
- if (sock)
- if ((fd = Sockets.Install(sock)) != -1)
- return fd;
- else
- delete sock;
-
- if (!errno)
- return GUSI_error(ENOMEM);
- else
- return -1;
- }
-
-